AWS CDKでAPI Gatewayのカスタムドメイン環境を構築してみた
はじめに
おはようございます。CX事業本部の佐藤です。
AWS CDKでAPI Gatewayのカスタムドメイン環境を作ってみました。
環境
項目 | バージョン |
---|---|
macOS | Mojave 10.14.5 |
node | v10.16.0 |
npm | 6.9.0 |
AWS CDK | 1.15.0 (build bdbe3aa) |
CDKでカスタムドメイン環境を構築する
事前準備
カスタムドメイン環境を構築するには、事前にドメインの取得や証明書の取得が必要です。今回は無料で取得できるドメインで試しました。
ドメインの取得
freenomなどのドメインレジストラで、無料のドメインを取得しDNSの設定をします。弊社の以下のブログが参考になります。
https://dev.classmethod.jp/cloud/aws/mesoko-r53-cdn/
Certificate ManagerでSSL証明書を取得
弊社の以下のブログが参考になります。
https://dev.classmethod.jp/cloud/aws/certificate-manager-dns-validation-support/
パラメータストアにドメイン名と取得した証明書のARNを設定します。
後ほど、CDKから参照して使用するため、設定しておきます。
aws ssm put-parameter --type 'String' --name 'APIG_CUSTOM_DOMAIN_NAME' --value 'www.example.com' aws ssm put-parameter --type 'String' --name 'APIG_CERTIFICATE_ARN' --value 'arn:aws:XXXX'
CDKでAPI Gatewayを作成する
AWS CDKを使ってインフラを構築していきます。以下、サンプルコードです。
テスト用Lambdaコード
export async function handler(event: any): Promise<any> { return 'test api gateway!'; }
CDKのコード
import * as cdk from '@aws-cdk/core'; import * as lambda from '@aws-cdk/aws-lambda'; import * as apig from '@aws-cdk/aws-apigateway'; import { NODE_LAMBDA_LAYER_DIR } from './process/setup'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import * as ssm from '@aws-cdk/aws-ssm'; export class ApigSampleStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // パラメータストアからドメイン名と証明書のARNを取得 const ApigCustomDomainName = ssm.StringParameter.fromStringParameterName(this, 'CustomDomainName', 'APIG_CUSTOM_DOMAIN_NAME'); const ApigCertificateArn = ssm.StringParameter.fromStringParameterName(this, 'CertificateArn', 'APIG_CERTIFICATE_ARN'); // Lambda Functionの作成 const testFunction = new lambda.Function(this, 'TestFunction', { code: lambda.Code.fromAsset('src/lambda/handlers/api-gw'), functionName: 'testFunction', handler: 'test.handler', runtime: lambda.Runtime.NODEJS_10_X, memorySize: 256, }); // API Gatewayの作成 const api = new apig.RestApi(this, 'RestApi', { restApiName: 'test', // エンドポイントタイプの設定(SSL証明書を東京リージョンで作成したため、REGIONALで作成します。) endpointTypes: [ apig.EndpointType.REGIONAL ], // CORSの設定 defaultCorsPreflightOptions: { allowOrigins: apig.Cors.ALL_ORIGINS, allowMethods: ['POST', 'OPTIONS'], statusCode: 200, }, description: "テスト用" }); // カスタムドメインの設定 const domainName = new apig.DomainName(this, 'CustomDomain', { // fromCertificateArnで証明書を取得します certificate: Certificate.fromCertificateArn(this, 'Certificate', ApigCertificateArn.stringValue), // パラメータストアに登録したドメイン名を設定します domainName: ApigCustomDomainName.stringValue, // REGINALタイプでカスタムドメインを設定します endpointType: apig.EndpointType.REGIONAL }); // ベースパスマッピングの設定 // https://www.example.com/v1/がベースパスとなります。 domainName.addBasePathMapping(api, { basePath: 'v1' }); // testリソース作成 const testResource = api.root.addResource('test'); // POSTメソッドの作成 testResource.addMethod('POST', new apig.LambdaIntegration(testFunction, { connectionType: apig.ConnectionType.INTERNET, // 統合リクエストの設定 requestTemplates: { 'application/json': "$input.json('$')" }, // 統合レスポンスの設定(CORS) integrationResponses: [ { statusCode: '200', contentHandling: apig.ContentHandling.CONVERT_TO_TEXT, responseParameters: { 'method.response.header.Access-Control-Allow-Headers': "'Origin,Content-Type,Authorization'", 'method.response.header.Access-Control-Allow-Methods': "'POST,OPTIONS'", 'method.response.header.Access-Control-Allow-Origin': "'*'" }, responseTemplates: { 'application/json': "$input.json('$')" } } ], passthroughBehavior: apig.PassthroughBehavior.WHEN_NO_MATCH, proxy: false, }), { // メソッドレスポンスの設定(CORS) methodResponses: [ { statusCode: '200', responseParameters: { 'method.response.header.Access-Control-Allow-Headers': true, 'method.response.header.Access-Control-Allow-Methods': true, 'method.response.header.Access-Control-Allow-Origin': true } } ] } ); } }
デプロイ
AWSにデプロイします。
npm run build cdk deploy
動作確認
デプロイできたら、動作確認をしてみます。PostmanでAPIを呼び出してみます。Lambdaが実行されて、 レスポンスが返ってきています。
まとめ
AWS CDKでカスタムドメイン環境を構築してみました。当初は、CDK + Swaggerの構成を考えていたんですが、CDKのAPI GatewayライブラリがまだSwaggerのインポートに対応していないため、SwaggerはAPI仕様書として別管理とし、現状はCDK単体で構築するのが良いかと思います。誰かの参考になれば幸いです。